package com.srmt.common.retry;

/**
 * 重试配置类
 * 管理重试机制的各项参数
 * 
 * @author SRMT Development Team
 * @since 1.0.0
 */
public class RetryConfig {
    
    /**
     * 是否启用重试
     */
    private boolean enabled = true;
    
    /**
     * 最大重试次数
     */
    private int maxAttempts = 5;
    
    /**
     * 初始延迟时间（毫秒）
     */
    private long initialDelayMs = 1000;
    
    /**
     * 最大延迟时间（毫秒）
     */
    private long maxDelayMs = 32000;
    
    /**
     * 退避因子
     */
    private double backoffFactor = 2.0;
    
    /**
     * 是否启用随机抖动
     */
    private boolean jitterEnabled = true;
    
    /**
     * 是否对所有HTTP方法启用重试
     * true: 所有方法（GET、POST、PUT、DELETE等）都重试
     * false: 仅对幂等方法（GET）重试
     */
    private boolean retryAllMethods = true;
    
    /**
     * 默认构造函数
     */
    public RetryConfig() {
    }
    
    /**
     * 构建器模式
     */
    public static class Builder {
        private final RetryConfig config = new RetryConfig();
        
        public Builder enabled(boolean enabled) {
            config.enabled = enabled;
            return this;
        }
        
        public Builder maxAttempts(int maxAttempts) {
            if (maxAttempts < 1) {
                throw new IllegalArgumentException("最大重试次数必须至少为1");
            }
            config.maxAttempts = maxAttempts;
            return this;
        }
        
        public Builder initialDelayMs(long initialDelayMs) {
            if (initialDelayMs < 0) {
                throw new IllegalArgumentException("初始延迟时间不能为负数");
            }
            config.initialDelayMs = initialDelayMs;
            return this;
        }
        
        public Builder maxDelayMs(long maxDelayMs) {
            if (maxDelayMs < 0) {
                throw new IllegalArgumentException("最大延迟时间不能为负数");
            }
            config.maxDelayMs = maxDelayMs;
            return this;
        }
        
        public Builder backoffFactor(double backoffFactor) {
            if (backoffFactor < 1.0) {
                throw new IllegalArgumentException("退避因子必须至少为1.0");
            }
            config.backoffFactor = backoffFactor;
            return this;
        }
        
        public Builder jitterEnabled(boolean jitterEnabled) {
            config.jitterEnabled = jitterEnabled;
            return this;
        }
        
        public Builder retryAllMethods(boolean retryAllMethods) {
            config.retryAllMethods = retryAllMethods;
            return this;
        }
        
        public RetryConfig build() {
            // 验证配置的合理性
            if (config.maxDelayMs < config.initialDelayMs) {
                config.maxDelayMs = config.initialDelayMs;
            }
            return config;
        }
    }
    
    /**
     * 创建构建器
     * 
     * @return 构建器实例
     */
    public static Builder builder() {
        return new Builder();
    }
    
    /**
     * 创建默认配置
     * 
     * @return 默认配置实例
     */
    public static RetryConfig defaultConfig() {
        return new RetryConfig();
    }
    
    // Getters and Setters
    
    public boolean isEnabled() {
        return enabled;
    }
    
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    
    public int getMaxAttempts() {
        return maxAttempts;
    }
    
    public void setMaxAttempts(int maxAttempts) {
        if (maxAttempts < 1) {
            throw new IllegalArgumentException("最大重试次数必须至少为1");
        }
        this.maxAttempts = maxAttempts;
    }
    
    public long getInitialDelayMs() {
        return initialDelayMs;
    }
    
    public void setInitialDelayMs(long initialDelayMs) {
        if (initialDelayMs < 0) {
            throw new IllegalArgumentException("Initial delay cannot be negative");
        }
        this.initialDelayMs = initialDelayMs;
    }
    
    public long getMaxDelayMs() {
        return maxDelayMs;
    }
    
    public void setMaxDelayMs(long maxDelayMs) {
        if (maxDelayMs < 0) {
            throw new IllegalArgumentException("Max delay cannot be negative");
        }
        this.maxDelayMs = maxDelayMs;
    }
    
    public double getBackoffFactor() {
        return backoffFactor;
    }
    
    public void setBackoffFactor(double backoffFactor) {
        if (backoffFactor < 1.0) {
            throw new IllegalArgumentException("Backoff factor must be at least 1.0");
        }
        this.backoffFactor = backoffFactor;
    }
    
    public boolean isJitterEnabled() {
        return jitterEnabled;
    }
    
    public void setJitterEnabled(boolean jitterEnabled) {
        this.jitterEnabled = jitterEnabled;
    }
    
    public boolean isRetryAllMethods() {
        return retryAllMethods;
    }
    
    public void setRetryAllMethods(boolean retryAllMethods) {
        this.retryAllMethods = retryAllMethods;
    }
    
    @Override
    public String toString() {
        return "RetryConfig{" +
                "enabled=" + enabled +
                ", maxAttempts=" + maxAttempts +
                ", initialDelayMs=" + initialDelayMs +
                ", maxDelayMs=" + maxDelayMs +
                ", backoffFactor=" + backoffFactor +
                ", jitterEnabled=" + jitterEnabled +
                ", retryAllMethods=" + retryAllMethods +
                '}';
    }
}